#include <iostream>
#include <pthread.h>
#include <string>
#include <unistd.h>
#include <vector>

/* 抢票系统 */
int ticket = 100;                                 /* 票数 */
pthread_mutex_t glock = PTHREAD_MUTEX_INITIALIZER; /* 全局锁 */

class ThreadData
{
public:
    ThreadData(const std::string &n, pthread_mutex_t &lock)
        : _name(n), _lock(lock)
    {
    }

    ~ThreadData()
    {
    }

    std::string _name;
    pthread_mutex_t &_lock;
};

void *routine(void *args)
{
    // std::string name = static_cast<const char *>(args);
    ThreadData *td = static_cast<ThreadData *>(args);
    while (true)
    {
        /* 使用全局锁,加锁 */
        // pthread_mutex_lock(&glock);
        /* 加锁，局部锁 */
        pthread_mutex_lock(&td->_lock);
        if (ticket > 0)
        {
            usleep(1000);
            std::cout << td->_name.c_str() << " Get a ticket, having: " << ticket << " leave" << std::endl;
            ticket--;
            /* 解锁全局锁 */
            // pthread_mutex_unlock(&glock);
            /* 解锁局部锁 */
            pthread_mutex_unlock(&td->_lock);
        }
        else
        {
            /* 解锁全局锁 */
            // pthread_mutex_unlock(&glock);
            /* 解锁局部锁 */
            pthread_mutex_unlock(&td->_lock);
            break;
        }
    }
    delete td;
    return nullptr;
}

int main()
{
    /* 局部锁*/
    pthread_mutex_t lock;
    /* 初始化锁 */
    pthread_mutex_init(&lock, nullptr);
    std::vector<pthread_t> ptv(4);
    for(int i = 0; i < 4; ++i)
    {
        std::string name = "Thread-" + std::to_string(i);
        ThreadData* td = new ThreadData(name, lock);
        pthread_create(&ptv[i], nullptr, routine, td);
    }

    for(auto& e : ptv)
    {
        pthread_join(e, nullptr);
    }

    /* 销毁锁 */
    pthread_mutex_destroy(&lock);
    return 0;
}